package jme3

import Greeting
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material.Button
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.awt.SwingPanel
import androidx.compose.ui.graphics.Color.Companion.Black
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.jme3.app.SimpleApplication
import com.jme3.material.Material
import com.jme3.math.ColorRGBA
import com.jme3.scene.Geometry
import com.jme3.system.JmeCanvasContext
import com.jme3.scene.shape.Box
import com.jme3.system.AppSettings

import kotlinx.datetime.Clock
import kotlinx.datetime.LocalDateTime
import kotlinx.datetime.TimeZone
import kotlinx.datetime.toLocalDateTime
import org.jetbrains.compose.resources.ExperimentalResourceApi
import org.jetbrains.compose.resources.painterResource
import java.awt.BorderLayout
import java.awt.Dimension
import java.awt.Graphics2D
import javax.swing.BoxLayout
import javax.swing.JButton
import javax.swing.JPanel

//JME3的SwingCanvas， 测试放到Compose中, jme3-lwjgl 不能用3
class Jme3DCanvasTest : SimpleApplication() {
    override fun simpleInitApp() {
        flyCam.isDragToRotate = true
        val b = Box(1f, 1f, 1f) // create cube shape
        val geom = Geometry("Box", b) // create cube geometry from the shape
        val mat = Material(
            assetManager,
            "Common/MatDefs/Misc/Unshaded.j3md"
        ) // create a simple material
        mat.setColor("Color", ColorRGBA.Blue) // set color of material to blue
        geom.material = mat // set the cube's material
        rootNode.attachChild(geom) // make the cube appear in the scene
    }
}

@Composable
fun JME3DApp() {
    Column(horizontalAlignment = Alignment.CenterHorizontally) {
        Text(text = "Jme3D")
        Box(
            modifier=  Modifier.fillMaxSize().padding(2.dp),
//            border = BorderStroke(2.dp,Color.Red),
//            backgroundColor = Color.Yellow
        ){
            SwingPanel (
                factory = {
                    val canvasApplication = Jme3DTestSceneStress()
                    canvasApplication.createCanvas() // create canvas!
                    val ctx = canvasApplication.context as JmeCanvasContext
                    ctx.systemListener = canvasApplication
                    //why useless??
                    //直接返回canvas 设置无效，
                    //要控制size，放到panel中
//                    val dim = Dimension(100, 100)
//                    ctx.canvas.preferredSize = dim

                    val panel: JPanel = object : JPanel(BorderLayout()) {
                        override fun doLayout() {
//                                val graphicsConfiguration =
//                                    GraphicsEnvironment.getLocalGraphicsEnvironment().defaultScreenDevice.defaultConfiguration
//                                val displayTransform = graphicsConfiguration.defaultTransform
//                                val scaleX =
//                                    displayTransform.scaleX // Windows OS Display X scaling.
//                                val scaleY =
//                                    displayTransform.scaleY // Windows OS Display Y scaling.
                            val g2d = graphics as Graphics2D
                            val globalTransform = g2d.transform
                            val scaleX = globalTransform.scaleX
                            val scaleY = globalTransform.scaleY
                            println("scaleX:$scaleX scaleY:$scaleY")
                            ctx.canvas.setBounds(
                                0,
                                0,
                                (width * scaleX).toInt(),
                                (height * scaleY).toInt()
                            )
                        }
                    }
                    panel.add(ctx.canvas, BorderLayout.CENTER)
                    panel
                }
            )
        }
    }
}

@OptIn(ExperimentalResourceApi::class)
@Composable
fun App() {
    MaterialTheme {
        var greetingText by remember { mutableStateOf("Hello World!") }
        var showImage by remember { mutableStateOf(false) }
        Column(Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally) {
            Text(
                text = "Today's date is ${todaysDate()}",
                modifier = Modifier.padding(20.dp),
                fontSize = 24.sp,
                textAlign = TextAlign.Center
            )
            Button(onClick = {
                greetingText = "Compose: ${Greeting().greet()}"
                showImage = !showImage
            }) {
                Text(greetingText)
            }
            AnimatedVisibility(showImage) {
                //show Image ?
                Image(
                    painter = painterResource("compose-multiplatform.xml"),
                    contentDescription = "JetBrains Logo",
                )
            }
            //在Compose中使用SwingPanel使用Swing组件
            Box(modifier = Modifier.fillMaxWidth().height(400.dp).padding(2.dp) ){
                //Swing panel inside a composable
                SwingPanel(
                    background = Black,
                    factory = {
                        val settings = AppSettings(true)

                        val canvasApplication = Jme3DCanvasTest()
                        canvasApplication.createCanvas() // create canvas!
                        canvasApplication.setSettings(settings)

                        val ctx = canvasApplication.context as JmeCanvasContext
                        ctx.systemListener = canvasApplication
                        //不设置显示为0
                        val dim = Dimension(300, 200)
                        ctx.canvas.preferredSize = dim

                        //The block creating the Component to be composed.
                        val button = JButton("Swing Button")
                        val panel = JPanel()
                        //设置panel size没有效果
                        panel.preferredSize = Dimension(200, 200)
                        panel.addFocusListener(object : java.awt.event.FocusAdapter() {
                            override fun focusGained(e: java.awt.event.FocusEvent?) {
                                println("focusGained")
                            }

                            override fun focusLost(e: java.awt.event.FocusEvent?) {
                                println("focusLost")
                            }
                        })

                        //add click
                        button.addActionListener {
                            println("button click ${ctx.canvas.isShowing}")
                            ctx.systemListener.gainFocus() //when to lose focus?
                            panel.revalidate()
                        }

                        button.preferredSize = Dimension(60,40)
                        panel.add(button, BoxLayout.X_AXIS)
                        panel.add(ctx.canvas, BoxLayout.X_AXIS)

                        return@SwingPanel panel
//                        panel.add(SwingCanvas())
                    },
                    update = {
                        println("swing panel update")
                    }
                )
            }
        }
    }
}

fun todaysDate(): String {
    fun LocalDateTime.format() = toString().substringBefore('T')

    val now = Clock.System.now()
    val zone = TimeZone.currentSystemDefault()
    return now.toLocalDateTime(zone).format()
}